#ifndef FRAMEDATA_H
#define FRAMEDATA_H

#include "dpvs.h"

namespace eqPc
{
    /**
     * Frame-specific data.
     *
     * The frame-specific data is used as a per-config distributed object and
     * contains mutable, rendering-relevant data. Each rendering thread (pipe)
     * keeps its own instance synchronized with the frame currently being
     * rendered. The data is managed by the Config, which modifies it directly.
     */
    class FrameData : public co::Serializable
    {
    public:
        FrameData();

        virtual ~FrameData() {};

        void reset();
        
        /** @name Rendering flags. */
        //*{
        void setModelID( const eq::uint128_t& id );

        void setColorMode( const ColorMode color );
        void setRenderMode( const pc::RenderMode mode );
        void setIdle( const bool idleMode );

        void toggleOrtho();
        void toggleStatistics();
        void toggleHelp();
        void toggleWireframe();
        void toggleColorMode();
        void adjustQuality( const float delta );
        void togglePilotMode();
        void toggleRenderMode();
        void toggleCompression();

        eq::uint128_t getModelID() const { return _modelID; }
        ColorMode getColorMode() const { return _colorMode; }
        float getQuality() const { return _quality; }
        bool useOrtho() const { return _ortho; }
        bool useStatistics() const { return _statistics; }
        bool showHelp() const { return _help; }
        bool useWireframe() const { return _wireframe; }
        bool usePilotMode() const { return _pilotMode; }
        bool isIdle() const { return _idle; }
        pc::RenderMode getRenderMode() const { return _renderMode; }
        bool useCompression() const { return _compression; }
        //*}

        /** @name Camera parameters. */
        //*{
        void setCameraPosition( const eq::Vector3f& position );
        void setRotation( const eq::Vector3f& rotation);
        void setModelRotation( const eq::Vector3f& rotation    );
		void setCameraRotation( const eq::Matrix4f& rotation ){ 

			_rotation.array[0]=rotation.array[0];_rotation.array[1]=rotation.array[1];_rotation.array[2]=rotation.array[2];
			_rotation.array[4]=rotation.array[4];_rotation.array[5]=rotation.array[5];_rotation.array[6]=rotation.array[6];
			_rotation.array[8]=rotation.array[8];_rotation.array[9]=rotation.array[9];_rotation.array[10]=rotation.array[10];
			setDirty( DIRTY_CAMERA );

		}
        void spinCamera( const float x, const float y );
        void spinModel(  const float x, const float y, const float z );
        void moveCamera( const float x, const float y, const float z );

        const eq::Matrix4f& getCameraRotation() const
            { return _rotation; }
        const eq::Matrix4f& getModelRotation() const
            { return _modelRotation; }
        const eq::Vector3f& getCameraPosition() const
            { return _position; }
        //*}

        /** @name View interface. */
        //*{
        void setCurrentViewID( const eq::uint128_t& id );
        eq::uint128_t getCurrentViewID() const { return _currentViewID; }
        //*}

        /** @name Message overlay. */
        //*{
        void setMessage( const std::string& message );
        const std::string& getMessage() const { return _message; }
        //*}

    protected:
        /** @sa Object::serialize() */
        virtual void serialize( co::DataOStream& os,
                                const uint64_t dirtyBits );
        /** @sa Object::deserialize() */
        virtual void deserialize( co::DataIStream& is,
                                  const uint64_t dirtyBits );

        virtual ChangeType getChangeType() const { return DELTA; }

        /** The changed parts of the data since the last pack(). */
        enum DirtyBits
        {
            DIRTY_CAMERA  = co::Serializable::DIRTY_CUSTOM << 0,
            DIRTY_FLAGS   = co::Serializable::DIRTY_CUSTOM << 1,
            DIRTY_VIEW    = co::Serializable::DIRTY_CUSTOM << 2,
            DIRTY_MESSAGE = co::Serializable::DIRTY_CUSTOM << 3,
        };

    private:
        eq::Matrix4f _rotation;
        eq::Matrix4f _modelRotation;
        eq::Vector3f _position;
        
        eq::uint128_t _modelID;
        pc::RenderMode _renderMode;
        ColorMode        _colorMode;
        float            _quality;
        bool             _ortho;
        bool             _statistics;
        bool             _help;
        bool             _wireframe;
        bool             _pilotMode;
        bool             _idle;
        bool             _compression;

        eq::uint128_t _currentViewID;
        std::string _message;
    };
}


#endif // EQ_PLY_FRAMEDATA_H
